﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace FinMkts
{
    /// <summary>
    /// A calendar that is the comination of several other calendars
    /// </summary>
    /// <example>Combining NY and London calendars</example>
    public class CombinedBusinessCalendar : BusinessCalendar
    {
        /// <summary>
        /// The calendars that are being combined
        /// </summary>
        public IEnumerable<BusinessCalendar> Combines { get; set; }       

        /// <summary>
        /// Are all calendars normally open
        /// </summary>
        /// <param name="when"></param>
        /// <returns></returns>
        public override bool IsNormallyOpen(DateTimeOffset when)
        {
            return Combines.All(calendar => calendar.IsNormallyOpen(when));
        }

        /// <summary>
        /// Are any calendars on holiday?
        /// </summary>
        public override bool IsOnHoliday(DateTimeOffset when)
        {
            return Combines.Any(calendar => calendar.IsOnHoliday(when));
        }

        public override DateTimeOffset NextOpens(DateTimeOffset when)
        {
            // the first point where all are open
            return (from c in Combines
                    let next = c.NextOpens(when)
                    orderby next ascending 
                    where IsOpen(next)      // all are open
                    select next).First();
        }

        public override DateTimeOffset NextCloses(DateTimeOffset when)
        {
            // the first point where any are closed
            return (from c in Combines
                    let next = c.NextCloses(when)
                    orderby next ascending 
                    select next).First();
        }
    }
}